#!/bin/sh
# - fs
# - format
# - mkfs
# - mount
# - mount_option
# - nr_tmpfs

# This script supports 2 NFS mount schemes:
# fs1: followup scripts will see NFS mount_points only
# fs2: followup scripts will see NFS mount_points as well as original mount_points

[ -n "$fs" ] || exit 0

. $LKP_SRC/lib/reproduce-log.sh
. $LKP_SRC/lib/fs_ext.sh
. $LKP_SRC/lib/debug.sh

[ -n "$mount_option" ] && mount_option="-o $mount_option"

def_mount=
def_mkfs=
fs_options() {
	case $fs in
	xfs)
		def_mount="-o inode64"
		[ "${raid_level#*raid}" != "$raid_level" ] && [ "$nr_partitions" -gt 1 ] && {
			def_mount="${def_mount},logbsize=262144"
			def_mkfs="-f -d agcount=$nr_partitions"
		}
		# mkfs.xfs v4.20.0 would set reflink=0 by default
		# mkfs.xfs v5.10.0 would set reflink=1 by default, and conflict with DAX mount option, so need to set reflink=0 explicitly
		ensure_mkfs='-f -mreflink=0'
		;;
	ext2)
		ensure_mkfs='-q -F'
		;;
	ext4)
		ensure_mkfs='-q -E lazy_itable_init=0,lazy_journal_init=0 -F'
		;;
	btrfs)
		;;
	f2fs)
		modprobe f2fs 2>/dev/null
		;;
	nfsv3)
		def_mount="-o vers=3"
		fs="nfs"
		;;
	nfsv4)
		def_mount="-o vers=4"
		fs="nfs"
		;;
	# https://www.mankier.com/8/mount.cifs
	cifs)
		;;
	smbv2)
		def_mount="-o vers=2.0"
		;;
	smbv2p1)
		def_mount="-o vers=2.1"
		;;
	smbv3)
		def_mount="-o vers=3.0"
		;;
	smbv3p02)
		def_mount="-o vers=3.02"
		;;
	smbv3p11)
		def_mount="-o vers=3.11"
		;;
	cifs*|smb*)
		die "unknow cifs/smb version"
		;;
	udf)
		;;
	ocfs2)
		ensure_mkfs='-q -F'
		;;
	esac
}

is_btrfs_raid_levels() {
	[ "$fs" = 'btrfs' ] && [ "$raid_level" = 'braid0' -o \
				 "$raid_level" = 'braid1' -o \
				 "$raid_level" = 'braid5' -o \
				 "$raid_level" = 'braid6' -o \
				 "$raid_level" = 'braid10' ]
}

make_fs() {
	is_btrfs_raid_levels && {
		log_cmd mkfs.btrfs --data ${raid_level#b} -m ${raid_level#b} $mkfs $ensure_mkfs $partitions || exit
		return
	}

	[ "$fs" = 'ocfs2' ] && {
		start_o2cb || exit
	}

	local pids=
	for dev in $bdevs
	do
		if [ ! "$format" = 'n' ]; then
			log_cmd mkfs -t $fs ${mkfs:-$def_mkfs} $ensure_mkfs $dev &
		fi
		pids="${pids} $! "
	done

	local pid
	for pid in $pids; do
		wait $pid || exit
	done
}

probe_filesystem()
{
	local fs=$1
	grep -w $fs /proc/filesystems || log_cmd modprobe $fs
}

mount_fs() {
	for dev in $bdevs
	do
		local mnt=/fs/$(basename $dev)
		log_cmd mkdir -p $mnt
		probe_filesystem $fs
		if ! is_null_blk $dev && ! is_mount_on_root $dev; then
			log_cmd mount -t $fs ${mount:-$def_mount} $mount_option $dev $mnt || exit
		fi
		mount_points="${mount_points}$mnt "
	done
}

if is_btrfs_raid_levels; then
	bdevs="${partitions%% *}"
else
	bdevs="$partitions"
fi

fs_options

case $fs in
	nfs)
		start_nfsd $mount_points
		mount_local_nfs $mount_points
		[ "${0#*fs1}" != "$0" ] && mount_points=
		;;
	cifs|smb*)
		start_smbd $mount_points
		mount_local_cifs $mount_points
		[ "${0#*fs1}" != "$0" ] && mount_points=
		;;


	tmpfs)
		: "${nr_tmpfs:=1}"
		mount_tmpfs $nr_tmpfs
		;;

	*)
		. $LKP_SRC/lib/fs_ext.sh
		if [ ! "$format" = 'n' ]; then
			if [ -n "$raid_device" ] || [ -n "$LKP_LOCAL_RUN" ]; then
				destroy_fs
			else
				destroy_devices
			fi
		fi
		make_fs
		mount_fs
		;;
esac

cat > "$TMP_RESULT_ROOT/post-run.fs" <<EOF

#!/bin/sh

umount_fs() {
	for mt in /nfs/* /fs/*; do
		mountpoint -q \$mt && umount \$mt
	done
}

umount_fs
EOF

if [ "${0#*fs2}" != "$0" ]; then
	fs_key=fs2
else
	fs_key=fs
fi

cat >> $TMP/env.yaml <<EOF

# setup/$fs_key
$fs_key: $fs
mount_points: $nfs_mount_points $cifs_mount_points $mount_points
cifs_mount_points: $cifs_mount_points
cifs_server_paths: $cifs_server_paths
nfs_mount_points: $nfs_mount_points
nfs_export_paths: $nfs_export_paths
EOF
